package pl.edu.uj.ii.battleships.activities;

import java.util.ArrayList;

import pl.edu.ii.uj.battleships.server.PackageClient;
import pl.edu.ii.uj.battleships.server.ServerHandler;
import pl.edu.uj.ii.battleships.R;
import pl.edu.uj.ii.battleships.adapters.GridAdapter;
import pl.edu.uj.ii.battleships.interfaces.Handler;
import pl.edu.uj.ii.battleships.models.BoardItem;
import pl.edu.uj.ii.battleships.models.BoardItem.Status;
import pl.edu.uj.ii.battleships.models.Ship;
import pl.edu.uj.ii.battleships.models.Ship.Type;
import pl.edu.uj.ii.battleships.utils.ConfigPropsManager;
import pl.edu.uj.ii.battleships.utils.GameDataManager;
import pl.edu.uj.ii.battleships.utils.Logger;
import pl.edu.uj.ii.battleships.utils.MessageFactory;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Message;
import android.view.*;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.View.OnClickListener;
import android.widget.*;
import android.widget.AdapterView.OnItemClickListener;

public class MyBoardActivity extends CustomActivity implements Handler {
	
    private static final int SWIPE_MIN_DISTANCE = 120;
    private static final int SWIPE_MAX_OFF_PATH = 250;
    private static final int SWIPE_THRESHOLD_VELOCITY = 200;
    private GestureDetector gestureDetector;
    
    class MyGestureDetector extends SimpleOnGestureListener {
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        	Logger.debug("Something is going on. Gesture detected");
	    Intent intent = new Intent(MyBoardActivity.this.getBaseContext(), OpponentBoardActivity.class);
 
            if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH) {
                return false;
            }
 
            // right to left swipe
            if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
	    		startActivity(intent);
	    		MyBoardActivity.this.overridePendingTransition(
					R.anim.slide_in_right,
					R.anim.slide_out_left
	    		);
            }
            return false;
        }
 
        // It is necessary to return true from onDown for the onFling event to register
        @Override
        public boolean onDown(MotionEvent e) {
	        	return true;
        }
    }

	public enum InsertStatus {
		FIVEMAST,
		FOURMAST,
		THREEMAST,
		TWOMAST
	}
	
	private OnItemClickListener itemClickListener = new OnItemClickListener() {

		public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
			BoardItem bi = adapter.getItem(position);
			Logger.debug("Item clicked. Position: " + position + " , Id: " + id + " Status: " + bi.getStatus());
			if(insertMode) {
				if(bi.getStatus().equals(Status.EMPTY)) {
					Ship s = null;
					//adapter.setStatus(position,Status.SHIP);
					if(currentStatus == InsertStatus.FIVEMAST) {
						s = adapter.placeShip(position, Type.FIVEMAST, placeDown.isChecked());
					} else if(currentStatus == InsertStatus.FOURMAST) { 
						s = adapter.placeShip(position, Type.FOURMAST, placeDown.isChecked());
					} else if(currentStatus == InsertStatus.THREEMAST) { 
						s = adapter.placeShip(position, Type.THREEMAST, placeDown.isChecked());
					} else if(currentStatus == InsertStatus.TWOMAST) { 
						s = adapter.placeShip(position, Type.TWOMAST, placeDown.isChecked());
					}
					
					if(s != null) {
						if(currentStatus == InsertStatus.FIVEMAST) {
							ships_fivemast.add(s);
						} else if(currentStatus == InsertStatus.FOURMAST) { 
							ships_fourmast.add(s);
						} else if(currentStatus == InsertStatus.THREEMAST) { 
							ships_threemast.add(s);
						} else if(currentStatus == InsertStatus.TWOMAST) { 
							ships_twomast.add(s);
						}
						
						int current = Integer.parseInt(String.valueOf(textview_count.getText()));
						
						if(current == 1)
							changeInsertion();
						else 
							textview_count.setText(String.valueOf(--current));
						
					} else {
						Context context = getApplicationContext();
						CharSequence text = "Wrong position! Try again.";
						int duration = Toast.LENGTH_LONG;

						Toast toast = Toast.makeText(context, text, duration);
						toast.show();
					} 
					
					refresh();
				}
			}
		}
	};
	
	private OnClickListener onButtonClickListener = new OnClickListener() {

		public void onClick(View v) {
			if(v.equals(button_start)){
				Logger.debug("Start button clicked.");
				//Toast toast = Toast.makeText(getApplicationContext(), "", Toast.)
				textview_info.setText("Waiting for other players...");
				//progressBar_waiting.setVisibility(View.VISIBLE);
				progressDialog = new ProgressDialog(v.getContext());
				progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
				progressDialog.setMessage("Waiting for other players...");
				progressDialog.show();
				button_start.setEnabled(false);
				
				Logger.debug("ProgressDialog is showing.");
			} else if(v.equals(button_change)) {
				Intent intent = new Intent(v.getContext(), OpponentBoardActivity.class);
				startActivityForResult(intent, 0);
			}
		}
		
	};
	
	GridView gridView;
	GridAdapter adapter;
	InsertStatus currentStatus;
	TextView textview_info;
	TextView textview_count;
	TextView textview_title;
	Button button_start;
	Button button_change;
	ProgressDialog progressDialog;
	ServerHandler serverHandler;
	ConfigPropsManager propsManager;
	CheckBox placeDown;
	
	boolean insertMode = false;
	boolean ingame = false;
	
	ArrayList<Ship> ships_fivemast = new ArrayList<Ship>();
	ArrayList<Ship> ships_fourmast = new ArrayList<Ship>();
	ArrayList<Ship> ships_threemast = new ArrayList<Ship>();
	ArrayList<Ship> ships_twomast = new ArrayList<Ship>();
	
	
	public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.board_layout);
        
        
        propsManager = new ConfigPropsManager(this);
        
        serverHandler = GameDataManager.getServerHandler();
        if(serverHandler == null)
        	serverHandler = new ServerHandler(propsManager, this);      
        
        serverHandler.setHandler(this);
        
        button_start = (Button)findViewById(R.id.button_start);
        button_start.setOnClickListener(onButtonClickListener);
        button_start.setEnabled(false);
        
        button_change = (Button)findViewById(R.id.button_change);
        button_change.setOnClickListener(onButtonClickListener);
        //button_change.setEnabled(false);
        
        
        gridView = (GridView)findViewById(R.id.gridview);
        gridView.setNumColumns(GameDataManager.getBoardWidth());
        
        adapter = new GridAdapter(this);
        gridView.setAdapter(adapter);
        
        gridView.setOnItemClickListener(itemClickListener);
        
        textview_info = (TextView)findViewById(R.id.textView_info);
        textview_count = (TextView)findViewById(R.id.textView_count);
        textview_title = (TextView)findViewById(R.id.textview_title);
        
        textview_title.setText("Your board");
        
        placeDown = (CheckBox)findViewById(R.id.insert_direction);
        
        if(GameDataManager.isServer()) {
	        if(GameDataManager.getFivemast() > 0) {
	        	currentStatus = InsertStatus.FIVEMAST;
	        	textview_info.setText("Place 5masts.");
	        	textview_count.setText(String.valueOf(GameDataManager.getFivemast()));
	        } else if(GameDataManager.getFourmast() > 0) {
	        	currentStatus = InsertStatus.FOURMAST;
	        	textview_info.setText("Place 4masts.");
	        	textview_count.setText(String.valueOf(GameDataManager.getFourmast()));
	        } else if(GameDataManager.getThreemast() > 0) {
	        	currentStatus = InsertStatus.THREEMAST;
	        	textview_info.setText("Place 3masts.");
	        	textview_count.setText(String.valueOf(GameDataManager.getThreemast()));
	        } else if(GameDataManager.getTwomast() > 0) {
	        	currentStatus = InsertStatus.TWOMAST;
	        	textview_info.setText("Place 2masts.");
	        	textview_count.setText(String.valueOf(GameDataManager.getTwomast()));
	        }  
	        insertMode = true;
        } else {
        	//wait for info about ships
        }
        
        
        
	}
	
	public void refresh() {
		adapter.notifyDataSetChanged();
		gridView.setAdapter(adapter);
	}
	
	public void changeInsertion(){
		Logger.debug("Change insertion called");
		if(currentStatus.equals(InsertStatus.FIVEMAST)){
			if(GameDataManager.getFourmast() > 0) {
	        	currentStatus = InsertStatus.FOURMAST;
	        	textview_info.setText("Place 4masts.");
	        	textview_count.setText(String.valueOf(GameDataManager.getFourmast()));
			} else if(GameDataManager.getThreemast() > 0) {
	        	currentStatus = InsertStatus.THREEMAST;
	        	textview_info.setText("Place 3masts.");
	        	textview_count.setText(String.valueOf(GameDataManager.getThreemast()));
	        } else if(GameDataManager.getTwomast() > 0) {
	        	currentStatus = InsertStatus.TWOMAST;
	        	textview_info.setText("Place 2masts.");
	        	textview_count.setText(String.valueOf(GameDataManager.getTwomast()));
	        }  else {
	        	insertingIsDone();
			}
		} else if(currentStatus.equals(InsertStatus.FOURMAST)) {
			if(GameDataManager.getThreemast() > 0) {
	        	currentStatus = InsertStatus.THREEMAST;
	        	textview_info.setText("Place 3masts.");
	        	textview_count.setText(String.valueOf(GameDataManager.getThreemast()));
	        } else if(GameDataManager.getTwomast() > 0) {
	        	currentStatus = InsertStatus.TWOMAST;
	        	textview_info.setText("Place 2masts.");
	        	textview_count.setText(String.valueOf(GameDataManager.getTwomast()));
	        }  else {
	        	insertingIsDone();
			}
		} else if(currentStatus.equals(InsertStatus.THREEMAST)) {
			if(GameDataManager.getTwomast() > 0) {
	        	currentStatus = InsertStatus.TWOMAST;
	        	textview_info.setText("Place 2masts.");
	        	textview_count.setText(String.valueOf(GameDataManager.getTwomast()));
	        } else {
	        	insertingIsDone();
			}
		} else {
			insertingIsDone();
		}
	}
	
	final android.os.Handler customHandler = new android.os.Handler(){
		public void handleMessage(Message msg){
			String s = (String)msg.obj;
			Logger.debug("Handler received msg: " + s);
			if(s.equals(MessageFactory.Prefix.GAME + MessageFactory.getDelimiter() + "start")) {
				startGame();
			}
		}
	};
	
	public android.os.Handler getHandler() {
		return customHandler;
	}
	
	public void startGame(){
		Logger.debug("Starting game. Player 1: " + GameDataManager.getMyNick() + "   Player 2: " + GameDataManager.getOpponentNick());
		gestureDetector = new GestureDetector(new MyGestureDetector());
		
        View mainview = (View) findViewById(R.id.mainView);
        
        // Set the touch listener for the main view to be our custom gesture listener
        mainview.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                if (gestureDetector.onTouchEvent(event)) {
                    return true;
                }
                return false;
            }
        });
        
        
        progressDialog.dismiss();
        Toast toast = Toast.makeText(getApplicationContext(), "Game started!", Toast.LENGTH_SHORT);
        toast.show();
        button_start.setVisibility(View.GONE);
        ingame = true;
        button_change.setEnabled(true);
        
	}
	
	public void insertingIsDone(){
    	textview_info.setText("Inserting is done.");
    	textview_count.setText("");
    	placeDown.setEnabled(false);
    	placeDown.setVisibility(View.GONE);
		insertMode = false;
		button_start.setEnabled(true);
		
    	//ClientDescription cd = new ClientDescription(GameDataManager.getMyNick(), serverHandler.getOutputStream());
    	PackageClient pc = new PackageClient(GameDataManager.getMyNick(), 1, "trolololo");
    	serverHandler.sendPackage(pc);
	}
}
